bitkeeper revision 1.22.2.4 (3e4300a2YBCCfKhkAv-qMwF-eDVQTQ)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Fri, 7 Feb 2003 00:41:06 +0000 (00:41 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Fri, 7 Feb 2003 00:41:06 +0000 (00:41 +0000)
Many files:
  Fast application -> guest-OS trap handling (no longer 'bounce' thru ring 0).

xen-2.4.16/arch/i386/entry.S
xen-2.4.16/arch/i386/i8259.c
xen-2.4.16/arch/i386/io_apic.c
xen-2.4.16/arch/i386/process.c
xen-2.4.16/arch/i386/traps.c
xen-2.4.16/include/asm-i386/irq.h
xen-2.4.16/include/asm-i386/processor.h
xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h
xenolinux-2.4.16-sparse/arch/xeno/kernel/traps.c
xenolinux-2.4.16-sparse/include/asm-xeno/hypervisor.h

index 910e1f19fcbda63c5f45fce5f0a31ae0ddcf794f..a26c96ccc1a69d0b86a899bee33c829e72ffa37d 100644 (file)
@@ -527,6 +527,7 @@ ENTRY(hypervisor_call_table)
         .long SYMBOL_NAME(do_set_debugreg)
         .long SYMBOL_NAME(do_get_debugreg)
         .long SYMBOL_NAME(do_update_descriptor)
+        .long SYMBOL_NAME(do_set_fast_trap)
         .rept NR_syscalls-(.-hypervisor_call_table)/4
         .long SYMBOL_NAME(sys_ni_syscall)
        .endr
index c9d4dfe670c6f103cdbc1f0782cdb743619fc096..9c6ccc2d936c3e1f037a690141041a8474d9811e 100644 (file)
@@ -46,7 +46,7 @@ BUILD_COMMON_IRQ()
 
 /*
  * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts:
- * (these are usually mapped to vectors 0x20-0x2f)
+ * (these are usually mapped to vectors 0x30-0x3f)
  */
     BUILD_16_IRQS(0x0)
 
@@ -64,7 +64,7 @@ BUILD_COMMON_IRQ()
     BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3)
     BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7)
     BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb)
-    BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
+    BUILD_16_IRQS(0xc)
 #endif
 
 #undef BUILD_16_IRQS
@@ -111,7 +111,7 @@ BUILD_COMMON_IRQ()
         IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
        IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
        IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
-       IRQLIST_16(0xc), IRQLIST_16(0xd)
+       IRQLIST_16(0xc)
 #endif
     };
 
@@ -344,7 +344,7 @@ void __init init_8259A(int auto_eoi)
      * outb_p - this has to work on a wide range of PC hardware.
      */
     outb_p(0x11, 0x20);        /* ICW1: select 8259A-1 init */
-    outb_p(0x20 + 0, 0x21);    /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */
+    outb_p(0x30 + 0, 0x21);    /* ICW2: 8259A-1 IR0-7 mapped to 0x30-0x37 */
     outb_p(0x04, 0x21);        /* 8259A-1 (the master) has a slave on IR2 */
     if (auto_eoi)
         outb_p(0x03, 0x21);    /* master does Auto EOI */
@@ -352,7 +352,7 @@ void __init init_8259A(int auto_eoi)
         outb_p(0x01, 0x21);    /* master expects normal EOI */
 
     outb_p(0x11, 0xA0);        /* ICW1: select 8259A-2 init */
-    outb_p(0x20 + 8, 0xA1);    /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */
+    outb_p(0x30 + 8, 0xA1);    /* ICW2: 8259A-2 IR0-7 mapped to 0x38-0x3f */
     outb_p(0x02, 0xA1);        /* 8259A-2 is a slave on master's IR2 */
     outb_p(0x01, 0xA1);        /* (slave's support for AEOI in flat mode
                            is to be investigated) */
index 190e6be36c88fdb9959beab9d10dfa83505c5bd2..c5ae3a3107895eca5d7b09b63a2478a414ff2b5e 100644 (file)
@@ -495,8 +495,10 @@ static int __init assign_irq_vector(int irq)
                return IO_APIC_VECTOR(irq);
 next:
        current_vector += 8;
-       if (current_vector == HYPERVISOR_CALL_VECTOR)
-               goto next;
+        /* XXX Skip the guestOS -> Xen syscall vector! XXX */
+       if (current_vector == HYPERVISOR_CALL_VECTOR) goto next;
+        /* XXX Skip the Linux/BSD fast-trap vector! XXX */
+        if (current_vector == 0x80) goto next;
 
        if (current_vector > FIRST_SYSTEM_VECTOR) {
                offset++;
index c8e81de6750d3ddc8271b6999bda086ccd921621..6ee5c93c0306198dc45dbbe3fae9554924c814f6 100644 (file)
@@ -326,6 +326,11 @@ void new_thread(struct task_struct *p,
 
     __save_flags(regs->eflags);
     regs->eflags |= X86_EFLAGS_IF;
+
+    /* No fast trap at start of day. */
+    p->thread.fast_trap_idx    = 0x20;
+    p->thread.fast_trap_desc.a = 0;
+    p->thread.fast_trap_desc.b = 0;
 }
 
 
@@ -363,12 +368,17 @@ void new_thread(struct task_struct *p,
 /* NB. prev_p passed in %eax, next_p passed in %edx */
 void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
+    extern struct desc_struct idt_table[];
     struct thread_struct *prev = &prev_p->thread,
         *next = &next_p->thread;
     struct tss_struct *tss = init_tss + smp_processor_id();
 
     unlazy_fpu(prev_p);
 
+    /* Switch the fast-trap handler. */
+    CLEAR_FAST_TRAP(&prev_p->thread);
+    SET_FAST_TRAP(&next_p->thread);
+
     tss->esp0 = next->esp0;
     tss->esp1 = next->esp1;
     tss->ss1  = next->ss1;
index 0ce294c9f48105aab283511c68929dbf4286612f..59f293c8f904c1eb94968ce433e5a1d50afa4239 100644 (file)
@@ -277,20 +277,21 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
      * Cunning trick to allow arbitrary "INT n" handling.
      * 
      * We set DPL == 0 on all vectors in the IDT. This prevents any INT <n>
-     * instruction from trapping to the appropriate vector, when that might not 
+     * instruction from trapping to the appropriate vector, when that might not
      * be expected by Xen or the guest OS. For example, that entry might be for
      * a fault handler (unlike traps, faults don't increment EIP), or might
      * expect an error code on the stack (which a software trap never
      * provides), or might be a hardware interrupt handler that doesn't like
-     * being called spuriously.  
+     * being called spuriously.
      * 
      * Instead, a GPF occurs with the faulting IDT vector in the error code.
-     * Bit 1 is set to indicate that an IDT entry caused the fault.
-     * Bit 0 is clear to indicate that it's a software fault, not hardware.
+     * Bit 1 is set to indicate that an IDT entry caused the fault. Bit 0 is 
+     * clear to indicate that it's a software fault, not hardware.
      * 
-     * NOTE: Vectors 3 and 4 are dealt with from their own handler. This is okay
-     * because they can only be triggered by an explicit DPL-checked instruction.
-     * The DPL specified by the guest OS for these vectors is NOT CHECKED!!
+     * NOTE: Vectors 3 and 4 are dealt with from their own handler. This is
+     * okay because they can only be triggered by an explicit DPL-checked
+     * instruction. The DPL specified by the guest OS for these vectors is NOT
+     * CHECKED!!
      */
     if ( (error_code & 3) == 2 )
     {
@@ -298,6 +299,7 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
         ti = current->thread.traps + (error_code>>3);
         if ( ti->dpl >= (regs->xcs & 3) )
         {
+            if ( (error_code>>3)==0x80 ) { printk("!!!\n"); BUG(); }
             gtb->flags = GTBF_TRAP_NOCODE;
             gtb->cs    = ti->cs;
             gtb->eip   = ti->address;
@@ -570,6 +572,43 @@ long do_set_trap_table(trap_info_t *traps)
 }
 
 
+long do_set_fast_trap(int idx)
+{
+    trap_info_t *ti;
+
+    /* Index 0 is special: it disables fast traps. */
+    if ( idx == 0 )
+    {
+        CLEAR_FAST_TRAP(&current->thread);
+        memset(idt_table+current->thread.fast_trap_idx, 0, 8);
+        current->thread.fast_trap_idx    = 0x20;
+        current->thread.fast_trap_desc.a = 0;
+        current->thread.fast_trap_desc.b = 0;
+        return 0;
+    }
+
+    /*
+     * We only fast-trap vectors 0x20-0x2f, and vector 0x80.
+     * The former range is used by Windows and MS-DOS.
+     * Vector 0x80 is used by Linux and the BSD variants.
+     */
+    if ( (idx != 0x80) && ((idx < 0x20) || (idx > 0x2f)) ) return -1;
+
+    ti = current->thread.traps + idx;
+
+    CLEAR_FAST_TRAP(&current->thread);
+
+    current->thread.fast_trap_idx    = idx;
+    current->thread.fast_trap_desc.a = (ti->cs << 16) | (ti->address & 0xffff);
+    current->thread.fast_trap_desc.b = 
+        (ti->address & 0xffff0000) | 0x8f00 | (ti->dpl&3)<<13;
+
+    SET_FAST_TRAP(&current->thread);
+
+    return 0;
+}
+
+
 long do_fpu_taskswitch(void)
 {
     current->flags |= PF_GUEST_STTS;
index 918f828ce634ca84b1610593ac239e7ca1497f82..936e5bc86c863c8f5145b7b9621beb06265ca7e3 100644 (file)
@@ -10,8 +10,6 @@
 #define SA_SHIRQ        0x04000000
 
 #define TIMER_IRQ 0
-/* 256 in architecture, minus 16 allocated to processor. */
-#define NR_IRQS 224
 
 extern void disable_irq(unsigned int);
 extern void disable_irq_nosync(unsigned int);
@@ -21,14 +19,14 @@ extern void enable_irq(unsigned int);
  * IDT vectors usable for external interrupt sources start
  * at 0x20:
  */
-#define FIRST_EXTERNAL_VECTOR  0x20
+#define FIRST_EXTERNAL_VECTOR  0x30
 
-#define SYSCALL_VECTOR         0x80   /* application -> OS     */
-#define KDBENTER_VECTOR                0x81   /* anyone      -> KDB    */
-#define HYPERVISOR_CALL_VECTOR 0x82   /* OS          -> monitor*/
+#define NR_IRQS (256 - FIRST_EXTERNAL_VECTOR)
+
+#define HYPERVISOR_CALL_VECTOR 0x82
 
 /*
- * Vectors 0x20-0x2f are used for ISA interrupts.
+ * Vectors 0x30-0x3f are used for ISA interrupts.
  */
 
 /*
@@ -55,11 +53,11 @@ extern void enable_irq(unsigned int);
 #define LOCAL_TIMER_VECTOR     0xef
 
 /*
- * First APIC vector available to drivers: (vectors 0x30-0xee)
- * we start at 0x31 to spread out vectors evenly between priority
- * levels. (0x80 is the syscall vector)
+ * First APIC vector available to drivers: (vectors 0x40-0xee)
+ * we start at 0x41 to spread out vectors evenly between priority
+ * levels. (0x82 is the syscall vector)
  */
-#define FIRST_DEVICE_VECTOR    0x31
+#define FIRST_DEVICE_VECTOR    0x41
 #define FIRST_SYSTEM_VECTOR    0xef
 
 extern int irq_vector[NR_IRQS];
index b3f496c5bc79dcad1dcc84985d5b6ada36b7a031..02868d5b2378d7203010e42f7e89c4ae16b30947 100644 (file)
@@ -10,6 +10,7 @@
 #include <asm/page.h>
 #include <asm/types.h>
 #include <asm/cpufeature.h>
+#include <asm/desc.h>
 #include <xeno/config.h>
 #include <hypervisor-ifs/hypervisor-if.h>
 
@@ -352,15 +353,23 @@ struct thread_struct {
 /* floating point info */
     union i387_union   i387;
 /* Trap info. */
+    int                 fast_trap_idx;
+    struct desc_struct  fast_trap_desc;
     trap_info_t         traps[256];
 };
 
+#define CLEAR_FAST_TRAP(_p) \
+    (memset(idt_table + (_p)->fast_trap_idx, 0, 8))
+#define SET_FAST_TRAP(_p)   \
+    (memcpy(idt_table + (_p)->fast_trap_idx, &((_p)->fast_trap_desc), 8))
+
 #define INIT_THREAD  {                                         \
        sizeof(idle0_stack) + (long) &idle0_stack, /* esp0 */   \
        0, 0, 0, 0, 0, 0,                                       \
        { [0 ... 7] = 0 },      /* debugging registers */       \
        0, 0, 0,                                                \
        { { 0, }, },            /* 387 state */                 \
+       0, { 0, 0 },                                            \
        { {0} }                 /* io permissions */            \
 }
 
index 9c9d752efd8e479d3386a8c79f87e3ccfffd6f95..a0cfc7ae5916de6b097d645ccab6c03f78d8e4ec 100644 (file)
@@ -88,6 +88,7 @@ typedef struct
 #define __HYPERVISOR_set_debugreg         11
 #define __HYPERVISOR_get_debugreg         12
 #define __HYPERVISOR_update_descriptor    13
+#define __HYPERVISOR_set_fast_trap        14
 
 #define TRAP_INSTR "int $0x82"
 
index 2a546b49d54d85c713c37698392883c914fb3087..c274928ae9e623bf1cada76e6156f58a603f94c3 100644 (file)
@@ -562,5 +562,6 @@ static trap_info_t trap_table[] = {
 void __init trap_init(void)
 {
     HYPERVISOR_set_trap_table(trap_table);    
+    HYPERVISOR_set_fast_trap(SYSCALL_VECTOR);
     cpu_init();
 }
index e6b2c13024ca89ac7f7f3f4ef7397cd914f0f13d..d25c6f8171506e9431f716729639023c72e369fd 100644 (file)
@@ -288,6 +288,16 @@ static inline int HYPERVISOR_update_descriptor(
         : "=a" (ret) : "0" (__HYPERVISOR_set_gdt), 
         "b" (pa), "c" (word1), "d" (word2) );
 
+    return ret;
+}
+
+static inline int HYPERVISOR_set_fast_trap(int idx)
+{
+    int ret;
+    __asm__ __volatile__ (
+        TRAP_INSTR
+        : "=a" (ret) : "0" (__HYPERVISOR_set_fast_trap), 
+        "b" (idx) );
 
     return ret;
 }